package token

import (
	"time"

	"github.com/golang-jwt/jwt/v4"

	"mxshop-api/shared/auth/token"
)

// JWTTokenGen generates a JWT token.
type JWTTokenGen struct {
	signingKey []byte
	issuer     string
	nowFunc    func() time.Time // 提取time.Now便于测试
	expire     time.Duration
}

// NewJWTTokenGen creates a JWTTokenGen.
func NewJWTTokenGen(signingKey, issuer string, expire int) *JWTTokenGen {
	return &JWTTokenGen{
		signingKey: []byte(signingKey), // 配置中的signingKey是string类型
		issuer:     issuer,
		nowFunc:    time.Now,
		expire:     time.Duration(expire) * time.Second, // 配置中的expire是int类型,默认单位是秒
	}
}

// GenerateToken generates a token.
func (t *JWTTokenGen) GenerateToken(custom token.Custom) (string, error) {
	nowTime := t.nowFunc()
	claims := token.CustomClaims{
		Custom: custom,
		RegisteredClaims: jwt.RegisteredClaims{
			Issuer:    t.issuer,
			IssuedAt:  jwt.NewNumericDate(nowTime),
			ExpiresAt: jwt.NewNumericDate(nowTime.Add(t.expire)),
		},
	}
	tokenEntity := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) // 生成token
	return tokenEntity.SignedString(t.signingKey)                    // 签名
}
